package M

import (
	"fmt"
	"net"
	"net/http"
	"regexp"
	"strings"
	"time"

	"gorm.io/gorm"
)

func (s *S) Print(a ...interface{}) {
	_, _ = fmt.Fprint(s.Res, a...)
}
func (s *S) DB() *gorm.DB {
	return Gorm(Server.DBconfig)
}
func (s *S) JSON(h interface{}) {
	s.Res.Header().Set("Content-Type", "application-json;charset=UTF-8")
	s.Print(Json_Encode(&h))
}
func (s *S) Encode(h interface{}) string {
	return Encode(Json_Encode(&h), Server.SiteKey)
}
func (s *S) Location(url string, code int) {
	s.Res.Header().Set("Cache-Control", "must-revalidate, no-store")
	s.Res.Header().Set("Content-Type", " text/html;charset=UTF-8")
	s.Res.Header().Set("Location", url) //跳转地址设置
	s.Res.WriteHeader(code)
}
func (s *S) GET(str string, v ...interface{}) string {
	old, ok := s.Get[str]
	if v != nil {
		v1 := ToStr(v[0])
		if v1 == "false" {
			//删除POST
			delete(s.Get, str)
		} else {
			s.Get[str] = v1
			return v1
		}
	}
	if ok {
		return old
	}
	return ""
}
func (s *S) POST(str string, v ...interface{}) string {
	old, ok := s.Post[str]
	if v != nil {

		if v[0] == nil {
			//删除POST
			delete(s.Post, str)
		} else {
			v1 := ToStr(v[0])
			s.Post[str] = v1
			return v1
		}
	}
	if ok {
		return old
	}
	return ""
}

/**
1、cook名称
2、cook值
3、过期时间秒
4、路径
5、域名
**/
func (s *S) COOKIE(name string, v ...interface{}) string {
	if len(v) > 0 {
		setcook := &http.Cookie{
			Name:   name,
			Value:  "",
			Path:   "/",
			Domain: s.Host,
		}
		if v[0] == nil {
			setcook.Value = ""
			setcook.MaxAge = -1
		} else {
			setcook.Value = ToStr(v[0])
		}
		if len(v) > 1 {
			setcook.MaxAge = ToInt(v[1])
		}
		if len(v) > 2 {
			setcook.Path = ToStr(v[2])
		}
		if len(v) > 3 {
			setcook.Domain = ToStr(v[3])
		}
		if vs := setcook.String(); vs != "" {
			s.Res.Header().Add("Set-Cookie", vs)
		} else {
			return ""
		}
		return setcook.Value
	}
	vs, err := s.Req.Cookie(name)
	if err == nil {
		return vs.Value
	}
	return ""
}

/**
1、session名称
2、session值 空值删除
**/
func (s *S) SESSION(name string, v ...interface{}) string {
	if len(v) > 0 {
		if v[0] == nil {
			s.ISession.Del(s.sessionid, name)
			return ""
		} else {
			v1 := ToStr(v[0])
			s.ISession.Set(s.sessionid, name, v1)
			return v1
		}
	}
	return s.ISession.Get(s.sessionid, name)
}
func (s *S) GetIp() string {
	xForwardedFor := s.Req.Header.Get("X-Forwarded-For")
	ip := strings.TrimSpace(strings.Split(xForwardedFor, ",")[0])
	if ip != "" {
		return ip
	}
	ip = strings.TrimSpace(s.Req.Header.Get("X-Real-Ip"))
	if ip != "" {
		return ip
	}
	if ip, _, err := net.SplitHostPort(strings.TrimSpace(s.Req.RemoteAddr)); err == nil {
		return ip
	}
	return ""
}

//输出文件
func (s *S) File(filepath string) {
	http.ServeFile(s.Res, s.Req, filepath)
}

//私有方法
//初始化GET
func (s *S) handleGet() {
	//初始化get
	s.Get = map[string]string{}
	for k, v := range s.Req.URL.Query() {
		s.Get[k] = v[0]
	}
}
func (s *S) handSession(config SessionConfig) {
	if !config.Start {
		return
	}
	if config.Type == "" {
		config.Type = "memory"
	}
	if config.Maxtime == 0 {
		config.Maxtime = int64(time.Hour) * 24
	}
	if config.Name == "" {
		config.Name = "GOSESSION"
	}
	if config.Name == "" {
		config.Name = "GOSESSION"
	}
	if config.Domain == "" {
		config.Domain = s.Host
	}

	//处理sessionid
	newid := false
	sessioncookie, err := s.Req.Cookie(config.Name)
	if err == nil {
		if sessioncookie.MaxAge == 0 {
			s.sessionid = sessioncookie.Value
		} else {
			newid = true
		}
	} else {
		newid = true
	}
	if newid == true {
		s.sessionid = Uid()
		setcook := &http.Cookie{
			Name:     config.Name,
			Value:    s.sessionid,
			Path:     "/",
			Domain:   config.Domain,
			HttpOnly: false,
		}
		s.Res.Header().Add("Set-Cookie", setcook.String())
	}
	//对接接口
	if config.Type == "memory" {
		s.ISession = Msession{}
		s.ISession.Init(config.Maxtime)
	}
}

//初始化POST
func (s *S) handlePost() {
	_ = s.Req.ParseForm()
	s.Post = map[string]string{}
	for k, v := range s.Req.PostForm {
		if len(v) < 1 {
			continue
		}
		s.Post[k] = v[0]
	}
}

func (s *S) GetHost() string {
	hosts := strings.Split(s.Req.Host, ":")
	if len(hosts) > 0 {
		return hosts[0]
	}
	return ""
}
func (s *S) GetPort() string {
	hosts := strings.Split(s.Req.Host, ":")
	if len(hosts) > 1 {
		return hosts[1]
	} else {
		return "80"
	}
}

/**
路由处理
**/
func (s *S) matchuri(uri string) bool {
	if uri == "" {
		return false
	}
	if uri == s.Path {
		return true
	}

	compile := regexp.MustCompile(`[{|\[|(](.*?)[}|\]|)]`)
	result := compile.FindAllStringSubmatch(uri, -1)
	for _, v := range result {
		border := string(v[0][0])
		if border == "{" {
			uri = strings.Replace(uri, v[0], "(.+?)", -1)
		}
		if border == "(" {
			uri = strings.Replace(uri, v[0], "([0-9]+?)", -1)
		}
		if border == "[" {
			uri = strings.Replace(uri, v[0], "([a-zA-Z0-9_]+)", -1)
		}
	}
	endcompole := regexp.MustCompile("startofuri-" + uri + "-endofuri")
	endrusle := endcompole.FindAllStringSubmatch("startofuri-"+s.Path+"-endofuri", -1)
	if len(endrusle) > 0 {
		s.Gets = map[string]string{}
		for k, v := range result {
			s.Gets[v[1]] = endrusle[0][k+1]
		}
		return true
	}
	return false
}

/**
路由入口域名绑定
**/
func (s *S) matchdomains(domains []string) bool {
	host := s.GetHost()
	//循环匹配如果为空 返回true
	if domains == nil {
		return true
	}
	for _, v := range domains {
		//转换小写
		domain := strings.ToLower(v)
		if domain == host || domain == "*" {
			return true
		}
		vindex := strings.Index(v, "*")
		if vindex != -1 {
			topdomain := v[vindex+1:]
			topsub := len(host) - len(topdomain)
			if topsub > 0 {
				downdomain := host[topsub:]
				if topdomain == downdomain {
					return true
				}
			}
			if "*."+host == v {
				return true
			}
		}
	}
	return false
}
